import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:myturngame/bean/bagobject/bag.dart';
import 'package:myturngame/bean/passive_effect.dart';
import 'package:myturngame/bean/skill/skill.dart';
import 'package:myturngame/common/game_global.dart';

import 'bagobject/equipment.dart';

class Role {
  String name;

  int level = 1;

  int hp = 0;
  int mp = 0;
  int maxExp = 10;
  int exp = 0;

  //基础属性
  List<int> baseAttrList = List.filled(AttributeSet.typeCount, 0);

  //装备属性
  List<int> equipmentAttrList = List.filled(AttributeSet.typeCount, 0);

  //已经分配的属性点
  List<int> allotPointAttrList = List.filled(AttributeSet.typeCount, 0);

  //可分配属性点
  int allotAttrPoint = 0;

  //最终结算属性
  List<int> finalAttrList = List.filled(AttributeSet.typeCount, 0);

  ///身上的装备
  //武器
  Equipment? equipWeapon;

  //头盔
  Equipment? equipHead;

  //衣服
  Equipment? equipBody;

  //鞋子
  Equipment? equipShoe;

  ///背包物品
  Bag bag = Bag();

  int money = 0;

  ///技能
  List<Skill> skills = [];

  ///套装被动效果
  Map<String, List<PassiveEffect>> effectMap = {};

  Role(this.name);

  ///增加经验值
  void addExp(int value) {
    exp += value;
  }

  ///升级
  void levelUp() {
    level++;
    exp -= maxExp;
    //提升最大经验值
    maxExp = (maxExp * 1.5).toInt();
    //基础属性增加
    for (var i in [
      AttributeSet.pointIndexPower,
      AttributeSet.pointIndexAgility,
      AttributeSet.pointIndexHealth,
      AttributeSet.pointIndexMagic,
      AttributeSet.pointIndexPatience,
    ]) {
      baseAttrList[i] += 1;
    }
    //自由分配的属性点增加
    allotAttrPoint += 5;
    //属性结算
    attributeSettlement();
    //当前血蓝回满
    hp = finalAttrList[AttributeSet.maxHp];
    mp = finalAttrList[AttributeSet.maxMp];
    // 保存数据
    GameGlobal.savePlayer();
  }

  ///增加属性点
  void addAttributePoint(int pointAttrIndex) {
    if (allotAttrPoint > 0) {
      allotPointAttrList[pointAttrIndex]++;
      allotAttrPoint--;
      attributeSettlement();
    }
  }

  ///减少属性点
  void minusAttributePoint(int pointAttrIndex) {
    if (allotPointAttrList[pointAttrIndex] > 0) {
      allotPointAttrList[pointAttrIndex]--;
      allotAttrPoint++;
      attributeSettlement();
    }
  }

  ///最终属性结算
  void attributeSettlement() {
    _pointSettlement(baseAttrList);
    _pointSettlement(equipmentAttrList);
    _pointSettlement(allotPointAttrList);

    var toSettlementAttrList = [
      AttributeSet.attack,
      AttributeSet.magicAttack,
      AttributeSet.maxHp,
      AttributeSet.maxMp,
      AttributeSet.defend,
      AttributeSet.speed,
      AttributeSet.pointIndexPatience,
      AttributeSet.pointIndexMagic,
      AttributeSet.pointIndexHealth,
      AttributeSet.pointIndexAgility,
      AttributeSet.pointIndexPower,
      AttributeSet.criticalRate,
      AttributeSet.criticalDamage,
    ];
    for (var e in toSettlementAttrList) {
      finalAttrList[e] =
          baseAttrList[e] + equipmentAttrList[e] + allotPointAttrList[e];
    }
  }

  bool isAlive() => hp > 0;

  bool isDead() => hp <= 0;

  void recoverHp() => hp = finalAttrList[AttributeSet.maxHp];

  int finalAttack() => finalAttrList[AttributeSet.attack];

  int finalMagicAttack() => finalAttrList[AttributeSet.magicAttack];

  int finalDefend() => finalAttrList[AttributeSet.defend];

  int finalSpeed() => finalAttrList[AttributeSet.speed];

  int finalMaxHp() => finalAttrList[AttributeSet.maxHp];

  int finalMaxMp() => finalAttrList[AttributeSet.maxMp];

  int finalCriticalRate() => min(finalAttrList[AttributeSet.criticalRate], 100);

  int finalCriticalDamage() => finalAttrList[AttributeSet.criticalDamage];

  ///属性点结算成属性
  void _pointSettlement(List<int> attributeList) {
    attributeList[AttributeSet.attack] =
        attributeList[AttributeSet.startAttack] +
            attributeList[AttributeSet.pointIndexPower] * 1;
    attributeList[AttributeSet.magicAttack] =
        attributeList[AttributeSet.startMagicAttack] +
            attributeList[AttributeSet.pointIndexMagic] * 1;
    attributeList[AttributeSet.maxHp] = attributeList[AttributeSet.startMaxHp] +
        attributeList[AttributeSet.pointIndexHealth] * 10;
    attributeList[AttributeSet.maxMp] = attributeList[AttributeSet.startMaxMp] +
        attributeList[AttributeSet.pointIndexMagic] * 5;
    attributeList[AttributeSet.defend] =
        (attributeList[AttributeSet.startDefend] +
                attributeList[AttributeSet.pointIndexPatience] * 0.5)
            .toInt();
    attributeList[AttributeSet.speed] = attributeList[AttributeSet.startSpeed] +
        attributeList[AttributeSet.pointIndexAgility] * 1;
  }

  ///套装属性状态刷新
  void bodySuitInvokeStateUpdate() {
    Map<String, int> suitCountMap = {};
    //遍历统计套装穿戴数量
    for (var equip in bodyEquipment()) {
      var suit = equip.suit;
      if (suit != null) {
        var count = suitCountMap[suit.name];
        if (count == null) {
          suitCountMap[suit.name] = 1;
        } else {
          suitCountMap[suit.name] = count + 1;
        }
      }
    }
    //遍历激活套装
    for (var equip in bodyEquipment()) {
      var suit = equip.suit;
      if (suit != null) {
        var count = suitCountMap[suit.name];
        if (count != null && count >= suit.invokeCount) {
          var suitEffects = suit.invoke();
          //添加被动效果
          _addEffect(suit.name, suitEffects);
        } else {
          var suitEffects = suit.notInvoke();
          //删除被动效果
          _removeEffect(suit.name, suitEffects);
        }
      }
    }
  }

  void _addEffect(String key,List<PassiveEffect> effects){
    if(effectMap[key]==null){
      effectMap[key] = effects;
      debugPrint("被动效果${effects.length} $key 添加");
    }
  }
  void _removeEffect(String key,List<PassiveEffect> effects){
    if(effectMap[key]!=null){
      effectMap.remove(key);
      debugPrint("被动效果${effects.length} $key 删除");
    }
  }

  ///返回身上穿戴的装备
  List<Equipment> bodyEquipment() {
    var bodyEquip = <Equipment>[];
    if (equipShoe != null) {
      bodyEquip.add(equipShoe!);
    }
    if (equipBody != null) {
      bodyEquip.add(equipBody!);
    }
    if (equipWeapon != null) {
      bodyEquip.add(equipWeapon!);
    }
    if (equipHead != null) {
      bodyEquip.add(equipHead!);
    }
    return bodyEquip;
  }
}

///属性集合
class AttributeSet {
  static const int maxHp = 0;
  static const int maxMp = 1;

  static const int attack = 2;
  static const int magicAttack = 3;
  static const int defend = 4;
  static const int speed = 5;

  static const int startMaxHp = 6;
  static const int startMaxMp = 7;
  static const int startAttack = 8;
  static const int startMagicAttack = 9;
  static const int startDefend = 10;
  static const int startSpeed = 11;

  //五种属性点
  static const int pointIndexPower = 12;
  static const int pointIndexMagic = 13;
  static const int pointIndexPatience = 14;
  static const int pointIndexAgility = 15;
  static const int pointIndexHealth = 16;

  //暴击率
  static const int criticalRate = 17;
  static const int criticalDamage = 18;

  //属性总数
  static const int typeCount = 19;
}
